#include "mainwindow.h"
#include "ui_mainwindow.h"

#if _MSC_VER >=1600
#pragma execution_character_set("utf-8")
#endif

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Init();
}
MainWindow::~MainWindow()
{
    delete ui;
    delete m_timer;
    delete readseting;
    delete m_analysis;
    delete m_msg_dialog;
}
//初始化程序
void MainWindow::Init()
{
    qDebug()<<" UI主线程id=="<<QThread::currentThreadId();
    //显示本地ip
    QString localip = Get_LocalIp();
    ui->ip_Edit->setText(localip);
    //显示当前时间
    m_timer = new QTimer(this);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(timerShow()));
    m_timer->setInterval(1000);
    m_timer->start();
    //自动保存log
    m_logtimer = new QTimer(this);
    connect(m_logtimer, SIGNAL(timeout()), this, SLOT(WriteHistoricalMessage()));
    m_logtimer->setInterval(120000);
    m_logtimer->start();
    //表格初始化
    table_dataInit();
    //创建解析对象
    m_analysis = new analysis_modbus;
    connect(this,&MainWindow::Start,m_analysis,&analysis_modbus::recvModbusMsg,
            Qt::QueuedConnection);
    connect(m_analysis,&analysis_modbus::analysis_over,this,&MainWindow::sendBackMsg,
            Qt::QueuedConnection);
    connect(m_analysis,&analysis_modbus::toUishowMsg,this,&MainWindow::ShowMsgString,
            Qt::QueuedConnection);
    connect(m_analysis,&analysis_modbus::toUishowMsgPack,this,&MainWindow::ShowMsgQByteArray,
            Qt::QueuedConnection);
    connect(m_analysis,&analysis_modbus::wirtTablec,this,&MainWindow::wirtTablec,
            Qt::QueuedConnection);
    connect(m_analysis,&analysis_modbus::wirtTabler,this,&MainWindow::wirtTabler,
            Qt::QueuedConnection);
    readseting = new QSettings("dataini/Data.ini", QSettings::IniFormat);
    ReadOutIniData();
    m_msg_dialog = new msgDialog(this);
}
//显示log消息
void MainWindow::on_add_serverMessage(QByteArray ba)
{
    ui->show_Edit->append(ba);
    ui->show_Edit->moveCursor(QTextCursor::End);
}
//显示异常信息
void MainWindow::ShowMsgString(QString error)
{
    ui->show_Edit->append(error);
    ui->show_Edit->moveCursor(QTextCursor::End);
}
//显示回应报文
void MainWindow::ShowMsgQByteArray(QByteArray ba)
{
    QString str;
    ByteToHexString(str,ba);
    ui->show_Edit->append("回应报文\r\n"+str);
    ui->show_Edit->moveCursor(QTextCursor::End);
}
//接收数据
void MainWindow::revcMsgfromChile(QByteArray ba)
{
    m_addr = (quint8)ui->addr->text().toInt();
    emit Start(ba,m_addr);
}
//发送回应报文
void MainWindow::sendBackMsg(QByteArray msg)
{
    for (int i=0;i<m_tcpServer->list_information.count();i++)
    {
        if(m_tcpServer->list_information[i].mysocket!=nullptr)
        {
            MySocket* mysocket = m_tcpServer->list_information[i].mysocket;
            emit mysocket->WriteMessage(msg);
        }
    }
}
//表格初始化
void MainWindow::table_dataInit()
{
    //设置表格
    QStringList TableHeader;
    TableHeader << "地址" << "数据";
    ui->table_coil->setVerticalHeaderLabels(TableHeader);
    ui->table_coil->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tableregs->setVerticalHeaderLabels(TableHeader);
    ui->tableregs->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tableregs->setEditTriggers(QAbstractItemView::NoEditTriggers);
    ui->table_coil->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
//将ini文件中的数据放到对应的表格中
void MainWindow::ReadOutIniData(void)
{
    for(int i = 0; i < (ADDRESS_MAX + 1); i++)
    {
        //地址设置
        QString adr =  "0x" + QString("%1").arg(i,4,16,QLatin1Char('0'));
        ui->table_coil->setItem(0,i, new QTableWidgetItem(QString(adr).toUpper()));
        ui->table_coil->item(0,i)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        ui->tableregs->setItem(0,i, new QTableWidgetItem(QString(adr)));
        ui->tableregs->item(0,i)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        //读出线圈数据
        QString coilData = readseting->value("Section" + QString::number(i+1) + "/coil").toString();
        //读出寄存器数据
        QString registerData = readseting->value("Section" + QString::number(i+1) + "/regi").toString();
        //在线圈数据表中显示数据
        ui->table_coil->setItem(1,i,new QTableWidgetItem(coilData));
        //设置表格内文字水平+垂直对齐
        ui->table_coil->item(1,i)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
        //在寄存器数据表中显示数据
        ui->tableregs->setItem(1,i,new QTableWidgetItem(registerData));
        //设置表格内文字水平+垂直对齐
        ui->tableregs->item(1,i)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    }
}
//更新寄存器表
void MainWindow::wirtTabler(quint16 num, quint16 satrtaddr,QVector<quint16> bar)
{
    ui->tableregs->blockSignals(true);
    for(int i = satrtaddr,k=0; k < num;k++,i++)
    {
      ui->tableregs->setItem(1,i,new QTableWidgetItem(QString("%1").arg(bar[k])));
      ui->tableregs->item(1,i)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    }
    ui->tableregs->blockSignals(false);
    bar.clear();
}
//更新线圈表
void MainWindow::wirtTablec(quint16 num, quint16 satrtaddr,QString bac)
{
    ui->table_coil->blockSignals(true);
    for(int i = satrtaddr,k=0; k < num;k++,i++)
    {
        //在线圈数据表中显示数据
        QString data;
        if(bac[k] == '1')
        {
            data ="1";
        }
        else
        {
            data ="0";
        }
        ui->table_coil->setItem(1,i,new QTableWidgetItem(data));
        ui->table_coil->item(1,i)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
    }
    ui->table_coil->blockSignals(false);
    bac.clear();
}
//显示时间
void MainWindow::timerShow()
{
    QDateTime current_date_time =QDateTime::currentDateTime();
    QString current_date =current_date_time.toString("yyyy.MM.dd hh:mm:ss ddd");
    ui->showTimer->setText(current_date);
}
//监听客户机连接
void MainWindow::on_tcp_listen_btn_clicked()
{

    if(this->m_tcpServer==nullptr)//未连接
    {
        if(judgement("是否启动监听？"))
        {
            bool ok=false;
            //获取监听的端口号
            quint16 port=ui->port_lineEdit->text().toUShort(&ok);
            if(!ok)
            {
                QMessageBox::warning(this,"错误","端口设置有误，请重新输入");
                return;
            }
            //获取监听的Ip
            QHostAddress ip(ui->ip_Edit->text());
            ip.toIPv4Address(&ok);
            if(!ok)
            {
                QMessageBox::warning(this,"错误","ip设置有误，请重新输入");
                return;
            }
            //创建server对象
            m_tcpServer=new MyServer(this);
            //设置线程数
            m_tcpServer->SetThread(5);
            //监听
            bool islisten = m_tcpServer->listen(ip, port);
            if(!islisten)
            {
                QMessageBox::warning(this,"错误",m_tcpServer->errorString());
                m_tcpServer->close();
                m_tcpServer->deleteLater();//释放
                m_tcpServer=nullptr;
                return;
            }
            //更新ui
            ui->tcp_listen_btn->setText("停止监听");
            ui->ip_Edit->setDisabled(true);
            ui->port_lineEdit->setDisabled(true);
        }
    }
    //停止server
    else
    {
        if(judgement("是否停止监听？"))
        {
            m_tcpServer->close();
            delete m_tcpServer;
            m_tcpServer=nullptr;
            //更新ui
            ui->tcp_listen_btn->setText("监听");
            ui->ip_Edit->setDisabled(false);
            ui->port_lineEdit->setDisabled(false);
        }
    }
}
//切换tab表格
void MainWindow::on_tabWidget_tabBarClicked(int index)
{
    switch(index){

    case 0 :bar_indexs=0;
        break;
    case 1 :bar_indexs=1;
        break;
    default:
        break;
    }
}
//定位到线圈表指定位置
void MainWindow::ReadOutIniDatac(int start)
{
    QTableWidgetItem* item = ui->table_coil->item(0,start);
    ui->table_coil->setCurrentItem(item);
    ui->table_coil->scrollToItem(item,QAbstractItemView::PositionAtCenter);
}
//定位到寄存器表指定位置
void MainWindow::ReadOutIniDatar(int start)
{
    QTableWidgetItem* item = ui->tableregs->item(0,start);
    ui->tableregs->setCurrentItem(item);
    ui->tableregs->scrollToItem(item,QAbstractItemView::PositionAtCenter);
}
//写入通信记录到Txt文件内
void MainWindow::WriteHistoricalMessage()
{

    //消息框内显示清除的时间，和文件夹路径
    QFileInfo info(RECORD_PATH);
    //时间
    timerShow();
    //消息窗口显示信息
    ui->show_Edit->append("保存至路径：" + info.filePath() + "\n文件名称：" + info.fileName()
                          + "\n文件大小：" + QString::number(info.size()) + "\n创建日期：" + info.created().toString("yyyy-MM-dd hh:mm:ss")
                          + "\n最后保存日期：" + info.lastModified().toString("yyyy-MM-dd hh:mm:ss") + "\n");

    //将历史记录写入文件，使用追加方式写入文件
    file = new QFile(RECORD_PATH);
    file->open(QFileDevice::Append);
    file->write(ui->show_Edit->toPlainText().toUtf8().data());
    //消息分块
    file->write("\n\n");
    //清除消息框中的内容
    ui->show_Edit->clear();
    file->close();
    delete file;
}
//起始地址和结束地址合法性检测
void MainWindow::on_check_2_clicked()
{
    int satrtaddr = ui->startaddr_2->text().toInt(NULL,10);
    if(bar_indexs==0)
    {
        if(satrtaddr>65535||satrtaddr<0)
        {
            QMessageBox::warning(this,"错误","起始地址超出范围，请重新输入!");
        }
        else
        {
            ReadOutIniDatac(satrtaddr);
        }
    }
    else if(bar_indexs==1)
    {
        if(satrtaddr>65535||satrtaddr<0)
        {
            QMessageBox::warning(this,"错误","起始地址超出范围，请重新输入!");
        }
        else
        {
            ReadOutIniDatar(satrtaddr);
        }
    }
}
//关闭程序事件
void MainWindow::closeEvent(QCloseEvent *event)
{
    if(judgement("确认退出程序？"))
    {
        //关闭界面，保存日志
        WriteHistoricalMessage();
        event->accept();
    }
    else
    {
        event->ignore();
    }
}
//更新本地IP
void MainWindow::on_refresh_ip_clicked()
{
    //显示本地ip
    QString localip = Get_LocalIp();
    ui->ip_Edit->setText(localip);
}
//从站地址限制
void MainWindow::on_addr_textChanged(const QString &arg1)
{
   int ad= arg1.toInt();
   if(ad>247||ad<1)
   {
    ui->addr->clear();
    QMessageBox::warning(this,"错误","从机地址1-247！");
   }
}
//清空窗口
void MainWindow::on_chear_clicked()
{
    if(judgement("是否清除窗口？"))
    {
        ui->show_Edit->clear();
    }
}
//查看历史记录
void MainWindow::on_check_clicked()
{
  wirteQStringtoTxt();
}
//读取历史文件信息
bool MainWindow::wirteQStringtoTxt()
{
    QString path = QFileDialog::getOpenFileName(this,"open","./","TXT(*.txt)");
    if(path.isEmpty() == false)
    {

        QMessageBox::information(this,"文件","选择路径成功！");
        //文件对象
        file = new QFile(path);
        //打开文件
        if(file->open(QIODevice::ReadWrite |QIODevice::Text)){
            QTextStream wstream(file);
            QString showmsg;
            showmsg = wstream.readAll();
            QMessageBox::information(this,"文件","打开成功！");
            file->close();
            delete file;
            m_msg_dialog->setMsg(showmsg.toLocal8Bit());
            m_msg_dialog->show();
            return true;
        }
        else
        {
            QMessageBox::information(this,"文件","打开失败！");
            delete file;
            return false;
        }
    }
    else
    {
        QMessageBox::information(this,"文件","选择路径失败！");
        delete file;
        return false;
    }
    return false;
}
//询问判断
bool MainWindow::judgement(QString msg)
{
    QMessageBox::StandardButton close;
    close = QMessageBox::question(this,"提示",msg,QMessageBox::Yes | QMessageBox::No,QMessageBox::No);

    if(close == QMessageBox::Yes)
    {
        return true;
    }
    else
    {
        return false;
    }
}
